package com.mayikt.rabbitmq;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import static com.mayikt.basic.Constants.*;


/**
 * @author 蚂蚁课堂创始人-余胜军QQ644064779
 * @title: RabbitMQConfig
 * @description: 每特教育独创第五期互联网架构课程
 * @date 2019/12/1021:40
 */
@Component
public class RabbitMQConfig {

    /*
        配置一个===========工作模型队列------不需要交换机
        默认均摊消费
     */
    @Bean("queueWork")
    public Queue queueWork() {
        return new Queue(MESSAGE_QUEUE);
    }
    /*
        配置一个===========发布订阅模型
     */
    // 声明一个 交换机
//    @Bean
    public Queue fanoutQueue() {
        return new Queue(FANOUT_QUEUE_NAME);
    }
//    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(FANOUT_EXCHANGE_NAME);
    }
    // 将交换机和队列进行绑定
//    @Bean
    public Binding messageBindingExchange(Queue fanoutQueue, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(fanoutQueue).to(fanoutExchange);
    }
    /*
      配置一个===========直连交换机 模型
    */
//    @Bean
    public Queue directQueue() {
        return new Queue(DIRECT_QUEUE_NAME);
    }

//    @Bean("smsQueue")
    public Queue smsQueue() {
        return new Queue(SMS_QUEUE_NAME);
    }
//    @Bean
    public DirectExchange exchangeDirect() {
        return new DirectExchange(DIRECT_EXCHANGE_NAME);
    }
//    @Bean
    public Binding bindingDirect1(Queue directQueue, DirectExchange exchangeDirect) {
        return BindingBuilder.bind(directQueue).to(exchangeDirect).with("order");
    }
//    @Bean
    public Binding bindingDirect2(Queue smsQueue, DirectExchange exchangeDirect) {
        return BindingBuilder.bind(smsQueue).to(exchangeDirect).with("sms");
    }
    /*
      配置一个===========topic 模型
    */
    @Bean
    public Queue topicQueue() {
        return new Queue(TOPIC_QUEUE_NAME);
    }
    @Bean
    public TopicExchange exchangeTopic() {
        return new TopicExchange(TOPIC_EXCHANGE_NAME);
    }
    @Bean
    public Binding bindingTopic1(Queue topicQueue, TopicExchange exchangeDirect) {
        return BindingBuilder.bind(topicQueue).to(exchangeDirect).with("topic.#");
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
//        rabbitTemplate.setChannelTransacted(true);//开启事务

        ////publisher-confirm-type参数配置为correlated时，使用此种方式确认消息是否成功发送到Exchange
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (!ack){//消息发送失败
                    System.out.println("消息未成功发送到交换机，原因为：" + cause);
                    return;
                }
                //消息发送成功
                System.out.println("消息确认成功发送到交换机");
            }
        });

//        rabbitTemplate.setMandatory(true);//开启监听回调
        //消息是否成功被路由到队列，没有路由到队列时会收到回调（原setReturnCallback在2.0版本已过期）
//        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
//            @Override
//            public void returnedMessage(ReturnedMessage returnedMessage) {
//                System.out.println("收到未路由到队列的回调消息：" + new String(returnedMessage.getMessage().getBody()));
//            }
//        });

        return rabbitTemplate;
    }
}
